CloudWatch Logs のメトリクスフィルタで、JSONに関するフィルターパターンを作成したときに、ログに対象の JSON 要素が存在しない場合は必ず結果がFALSEになる事象の解消方法
困っていること
CloudWatch Logs のロググループに下記のようなログが出力されています。(ログ上は 1 行ですが、便宜上改行しています)
{
"timestamp": "2023-05-15T14:32:18Z",
"level": "ERROR",
"service": "user-auth",
"message": "User login successful",
"user": {
"id": "12345",
"username": "johndoe",
"email": "john@example.com",
"phone": "08012345678"
}
}
また、phone
の要素が欠けるログが出力されることがあります。
{
"timestamp": "2023-05-15T14:32:18Z",
"level": "ERROR",
"service": "user-auth",
"message": "User login successful",
"user": {
"id": "54321",
"username": "gonbe",
"email": "gonbe@example.com",
}
}
CloudWatch Logs のロググループに下記のようなフィルターパターンを設定しました。
{ $.user.username="gonbe" && $.user.phone!="08000000000"}
$.user.phone!="08000000000"
としているので、その電話番号に一致しなくても検出されるはずです。
しかし、phone
要素がない場合に、フィルターパターンに一致しない問題が発生しています。
どのように解決すればいいですか?
どう解決すればいいの?
下記のようなフィルターパターンを設定した場合、phone
要素が存在しない場合は、結果が FALSE になります。
{ $.user.phone!="08000000000"}
NOT EXISTS
を使用すると、「ログデータのJSONにおいて特定のプロパティが存在しない場合はTRUE」というフィルターパターンを作成できます。or 条件でつなげることで、phone
要素が存在しない場合は全体の結果を TRUE とすることができます。
{ ($.user.phone!="08000000000") || ($.user.phone NOT EXISTS) }
やってみた
CloudWatch コンソールのロググループへアクセスします。
任意のロググループを選択し、「メトリクスフィルター」タブを開き、「メトリクスフィルターを作成」ボタンを押下します。
下記のログをテスト対象とします。
{"timestamp":"2023-05-15T14:32:18Z","level":"ERROR","service":"user-auth","message":"User login successful","user":{"id":"54321","username":"gonbe","email":"gonbe@example.com"}}
下記のフィルターパターンの場合は一致しませんでした。
{ $.user.username="gonbe" && $.user.phone!="08000000000"}
NOT EXISTS
を付与した条件を加えた場合は、一致しました。
{ $.user.username="gonbe" && (($.user.phone!="08000000000") || ($.user.phone NOT EXISTS)) }
参考資料
メトリクスフィルター、サブスクリプションフィルター、フィルターログイベント、およびライブテールのフィルターパターン構文 - Amazon CloudWatch Logs
簡単な表現を使用して JSON ログイベントで語句の一致 → Example: Filter pattern that matches JSON logs using NOT EXISTS
NOT EXISTS 変数を使用してフィルターパターンを作成し、ログデータに特定のフィールドを含まない JSON ログを返すことができます。次のフィルターパターンでは、NOT EXISTS を使用してフィールド SomeOtherObject を含まない JSON ログを返します。
{ $.SomeOtherObject NOT EXISTS }